<script setup lang="ts">

import HexGrid, {HexData} from "@/components/hex/HexGrid.vue";
import {reactive} from "vue";
import {HexGraph} from "@/components/hex/HexGraph";
import {hexPoints, transform} from "@/components/hex/HexComm";
import {HexPosition} from "@/components/hex/HexContainer";

interface CheckerHexCls {
  blink: boolean;
}

interface CheckerHexData extends HexData {
  piece?: string;
  cls: CheckerHexCls;
  preview: boolean;
}

const hexGraph = reactive(new HexGraph<CheckerHexData>(8, pos => ({
  onClick: onClick,
  cls: {
    blink: false,
  },
  preview: false,
  showHex: false,
  // hexAttrs: {stroke: 'none'},
  // text: [x, y, z].join(' '),
})));
hexGraph.forEvery(hex => {
  hex.fill = 'grey';
});
hexGraph.forNear([0, 0, 0], hex => {
  hex.fill = 'yellow';
}, 0, 4);
Object.entries({
  'red': [4, 4, -8],
  'lime': [-5, 4, 1],
  'aqua': [4, -5, 1],
}).forEach(([color, [cx, cy, cz]]) => {
  hexGraph.forNear([cx, cy, cz], (hex, [x, y, z]) => {
    if (x <= cx && y <= cy && z >= cz) {
      hex.fill = color;
      hex.piece = color;
    }
  }, 0, 3);
});
Object.entries({
  'blue': [-4, 8, -4],
  'green': [5, -1, -4],
  'purple': [-4, -1, 5],
}).forEach(([color, [cx, cy, cz]]) => {
  hexGraph.forNear([cx, cy, cz], (hex, [x, y, z]) => {
    if (x >= cx && y <= cy && z >= cz) {
      hex.fill = color;
      hex.piece = color;
    }
  }, 0, 3);
});

const radius = 30;
const hexTranslateGraph = new HexGraph(8, pos =>
    transform(pos, [400, 400], radius, 30)
)
const lineList: number[][] = [];
hexGraph.forEvery((hex, [x, y, z]) => {
  if (hex.fill !== 'grey') {
    hexGraph.forNear([x, y, z], (near, [nx, ny, nz]) => {
      if (near.fill !== 'grey' && x >= nx && y <= ny) {
        lineList.push([...hexTranslateGraph.get([x, y, z]), ...hexTranslateGraph.get([nx, ny, nz])])
      }
    });
  }
});
const trianglePositions: [string, HexPosition[]][] = [
  ['red', [[4, 4, -8], [0, 4, -4], [4, 0, -4]]],
  ['lime', [[-4, 4, 0], [-8, 4, 4], [-4, 0, 4]]],
  ['aqua', [[4, -4, 0], [0, -4, 4], [4, -8, 4]]],
  ['blue', [[-4, 8, -4], [0, 4, -4], [-4, 4, 0]]],
  ['green', [[4, 0, -4], [8, -4, -4], [4, -4, 0]]],
  ['purple', [[-4, 0, 4], [0, -4, 4], [-4, -4, 8]]]
];
const triangleMap: [string, string][] = trianglePositions.map(([c, a]) =>
    [c, a.map((pos) => hexTranslateGraph.get(pos).join(',')).join(' ')]
)
const centerPoints = hexPoints([400, 400], radius * 4 * Math.sqrt(3), 0);

let posA: [number, number, number] | undefined = undefined;
let posB: [number, number, number] | undefined = undefined;

function onClick(pos: HexPosition) {
  if (posA && posB) {
    posA = undefined;
    posB = undefined;
  }
  if (!posA) {
    if (!hexGraph.get(pos).piece) {
      return;
    }
    posA = pos;
    pick(pos);
  } else {
    if (hexGraph.get(pos).piece || !hexGraph.get(pos).preview) {
      put(posA);
      posA = undefined;
      return;
    }
    posB = pos;
    hexGraph.swap(posA, posB);
    put(pos);
  }
}

function pick(pos: HexPosition) {
  hexGraph.get(pos).cls.blink = true;
  showNearPreview(pos);
  showFarPreview(pos);
}

function put(pos: HexPosition) {
  hexGraph.get(pos).cls.blink = false;
  clearPreview();
}

function showNearPreview(pos: HexPosition): void {
  hexGraph.forNear(pos, near => {
    if (near.fill !== 'grey' && !near.piece) {
      near.preview = true;
    }
  })
}

function showFarPreview(pos: HexPosition): void {
  hexGraph.forNear(pos, (near, nearPos) => {
    if (near.piece) {
      hexGraph.forRay(pos, nearPos, (far, farPos) => {
        if (far.fill !== 'grey' && !far.piece && !far.preview) {
          far.preview = true;
          showFarPreview(farPos);
        }
      }, 2, 2);
    }
  })
}

function clearPreview(): void {
  hexGraph.forEvery(hex => {
    hex.preview = false;
  })
}

</script>

<template>
  <div class="main">
    <HexGrid
        :data="hexGraph"
        :radius="radius"
    >
      <template #back>
        <!-- 中心底色 -->
        <polygon
            :points="centerPoints"
            fill="yellow"
            stroke="none"
        />
        <!-- 六角底色 -->
        <template v-for="[color, points] in triangleMap">
          <polygon
              :points="points"
              :fill="color"
              stroke="none"
          />
        </template>
        <!-- 圆圈间连线 -->
        <template v-for="[x1,y1,x2,y2] in lineList">
          <line :x1="x1" :y1="y1" :x2="x2" :y2="y2"/>
        </template>
      </template>
      <template #cell="{hex, props}">
        <!-- 圆圈 -->
        <template v-if="hex.fill!== 'grey'">
          <circle
              :cx="props.translate[0]"
              :cy="props.translate[1]"
              :r="18"
              fill="white"
          />
        </template>
        <!-- 棋子 -->
        <template v-if="(hex as CheckerHexData).piece">
          <circle
              :cx="props.translate[0]"
              :cy="props.translate[1]"
              :r="10"
              :fill="(hex as CheckerHexData).piece"
              :class="(hex as CheckerHexData).cls"
          />
        </template>
        <!-- 下一步预览 -->
        <template v-if="(hex as CheckerHexData).preview">
          <circle
              :cx="props.translate[0]"
              :cy="props.translate[1]"
              :r="5"
              fill="orange"
          />
        </template>
        <!--        <text-->
        <!--            :x="props.translate[0]"-->
        <!--            :y="props.translate[1]"-->
        <!--        >-->
        <!--          {{ props.position.join(' ') }}-->
        <!--        </text>-->
      </template>
    </HexGrid>
  </div>
</template>

<style scoped>
/* 每隔 500 ms 显→隐→显 */
@keyframes blink {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}

.blink {
  animation: blink 1s infinite;
}
</style>